home *** CD-ROM | disk | FTP | other *** search
/ Chaos CD Blue / Chaos_CD_Blue__[1999].iso / contrib / software / bbpc / pcm.c < prev    next >
Text File  |  1998-04-27  |  7KB  |  271 lines

  1. /* compact memory model */
  2.  
  3.  
  4. #include <stdio.h>
  5. #include <io.h>
  6. #include <dos.h>
  7. #include <fcntl.h>
  8. #include <math.h>
  9. #include <alloc.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12.  
  13. #define PI             3.14159265358979323
  14.  
  15. #define TIMER0CLOCK 1193182L    /* Grundfreqenz des Timerbausteins */
  16. #define TIMER0DIV     70            /* divisor für timer 0 : sample time=30/CLOCK_FREQ = 25.1 uSec */
  17.  
  18. FILE *fpspeich;                    /* zur sofortigen speicherung des PCM-files */
  19. int portadr;                    /* printer port adresse */
  20. #define MAXARRAY 65000            /* maximale an Bytes im abspielfeld */
  21. #define MAXFIELDS 4                /* anzahl an abspielfeldern */
  22. long anzahl;                    /* anzahl im momentanen abspielfeld */
  23. long anzahlfeld[MAXFIELDS];        /* anzahl von zeichen die noch zu spielen sind (pro abspielfeld)*/
  24. char *memadr[MAXFIELDS];        /* zeiger auf alle die apspielfelder */
  25. long tmpanzahlfeld[MAXFIELDS];    /* feld um nur einzelne Stuecke abzuspielen */
  26. char *tmpmemadr[MAXFIELDS];     /* feld um nur einzelne Stuecke abzuspielen */
  27. char *memadr2;                    /* zeiger auf das naechste anzuspielende byte */
  28.  
  29. void interrupt (*old_vec)();    /* Adresse der alten Timerseviceroutine */
  30. void interrupt tic_once();        /* prototyp der abspielroutine */
  31.  
  32. void
  33. wave(f1, f2, tone)
  34. unsigned int f1, f2;    /* zwei freqenzen die sich ueberlagern */
  35. unsigned int tone;        /* dauer in mSekunden */
  36. {
  37.     double dt, dauer;
  38.     double freqtime;
  39.  
  40.     dt = (double)TIMER0DIV/(double)TIMER0CLOCK;    /* dauer eines abtastzeitpunktes */
  41.     dauer = (double)tone/(double)1000;
  42.     for (freqtime = 0; freqtime < dauer; freqtime += dt) {
  43.         if (f1 == 0  &&  f2 == 0)   tone = 0x80;
  44.         else   tone = 64   *   (2  +  (sin(2*PI*freqtime*f1) + sin (2*PI*freqtime*f2)));
  45.         if (tone >= 256)   tone = 255;
  46.         if (tone < 0)   tone = 0;
  47.         fputc(tone, fpspeich);
  48.     }
  49. }
  50.  
  51. void
  52. playtone()
  53. {
  54.     int i;
  55.     char old_0x21;
  56.  
  57.     disable();                    /* alle interrupts abschalten */
  58.  
  59.     old_vec = getvect(0x08);    /* alte Timerserviceroutine retten */
  60.     setvect(0x08, tic_once);    /* timerserviceroutine auf ton abspielen setzen */
  61.  
  62.     outportb(0x43, 0x14);        /* setzen der neuen abtastgeschwindigkeit */
  63.     outportb(0x40, TIMER0DIV);
  64.  
  65.     old_0x21 = inportb(0x21);    /* interrupt maske holen */
  66.     outportb(0x21, 0xFE);        /* nur Timer 0 einschalten */
  67.  
  68.     enable();                    /* jetzt gehts los  */
  69.  
  70.     for (i = 0; i < MAXFIELDS; i++) {    /* alle abspielfelder abspielen */
  71.         anzahl = tmpanzahlfeld[i];
  72.         memadr2 = tmpmemadr[i];
  73.         while (anzahl > 0L)   ;        /* warten bis alles ausgesendet wurde */
  74.     }
  75.  
  76.     disable();                    /* wieder keine Interrupts */
  77.  
  78.     outportb(0x21, old_0x21);    /* alte interrupt maske restaurieren */
  79.  
  80.     outportb(0x43, 0x34);        /* Timer0 wieder auf uebliche Zeitbasis (18.2Sekunden stellen */
  81.     outportb(0x40, 0x68);
  82.     outportb(0x40, 0xFF);
  83.  
  84.     setvect(0x08, old_vec);        /* alte timerserviceroutine wiederherstellen */
  85.  
  86.     enable();                    /* nun wieder normales don mit normalen interrupts */
  87. }
  88.  
  89. void interrupt tic_once()
  90. {
  91.     outportb(portadr, *memadr2);    /* ausgabe des neuen pcm-wertes */
  92.     memadr2++;
  93.     anzahl--;                       /* anzahl verringern */
  94.     outportb(0x20,0x20);            /* end of interrupt klarmachen */
  95. }
  96.  
  97. void readpcm(str)
  98. char *str;
  99. {
  100.     int i;
  101.     FILE *fp;
  102.  
  103.     fp = fopen(str, "rb");
  104.     if (fp != NULL) {
  105.         for (i = 0; i < MAXFIELDS; i++) {
  106.             if (anzahlfeld[i] == 0L) {    /* leeres Feld also File einlesen */
  107.                 while (anzahlfeld[i] < MAXARRAY  &&  !feof(fp)) {
  108.                     memadr[i][anzahlfeld[i]] = fgetc(fp);
  109.                     anzahlfeld[i]++;
  110.                 };
  111.             }
  112.         }
  113.         fclose(fp);
  114.     }
  115. }
  116.  
  117. void playfields()
  118. {
  119.     int i, j;
  120.     printf("-\nPCM-Playmodus...bitte File auswaehlen\n\n");
  121.     j = 0;
  122.     for (i = 0; i < MAXFIELDS; i++) {
  123.         if (anzahlfeld[i] > 0L  &&  (anzahlfeld[i] < MAXARRAY  ||  j == 0)) {
  124.             printf("File:%d\n", i+1);
  125.             j = 0;
  126.         }
  127.         if (anzahlfeld[i] >= MAXARRAY)   j = 1;
  128.     }
  129.     printf("Q = Quit\n");
  130.     do {
  131.  
  132.         for (i = 0; i < MAXFIELDS; i++) {    /* tmpfeld zuruecksetzen */
  133.             tmpanzahlfeld[i] = 0L;
  134.             tmpmemadr[i] = memadr[i];
  135.         }
  136.  
  137.         while(bioskey(1) == 0);
  138.  
  139.         i = bioskey(0);        /* taste einlesen */
  140.         if ((char)i == 'Q'  ||  (char)i == 'q')   return;
  141.         i = (char)i-49;
  142.         if (i < 0)   i = 0;
  143.         if (i >= MAXFIELDS)   i = MAXFIELDS-1;
  144.  
  145.         do {    /* nur das abzuspielende Feld einblenden */
  146.             tmpanzahlfeld[i] = anzahlfeld[i];
  147.             if (anzahlfeld[i] < MAXARRAY)   break;
  148.             i++;
  149.         } while (i < MAXFIELDS);
  150.         printf("playing... %d\r",i+1);
  151.                 fflush(stdout);
  152.         playtone();    /* Feld abspielen */
  153.         printf("             \r");
  154.                 fflush(stdout);
  155.     } while (42);
  156. }
  157.  
  158.  
  159. void main(argc, argv)
  160. int argc;
  161. char *argv[];
  162. {
  163.     char fstr2[80], fstr3[80];
  164.     char playfile[MAXFIELDS][80];
  165.     char string[80];
  166.     unsigned long anz;
  167.     FILE *fp;
  168.     int n, l, s, m, i, j, k;
  169.  
  170.     n = l = s = m = 0;
  171.     portadr = 0x378;
  172.     if (argc <= 1) {
  173.         printf("PCM-Soundprogramm (c) 1991 bei Hacko\n\n");
  174.         printf("-1 oder -2 oder -3 um dem Printerport festzulegen\n");
  175.         printf("-sX = schreiben PCM-File, wobei X der Name der Datei ist\n");
  176.         printf("-lX = lesen PCM-File, wobei X der Name der Dabei ist\n");
  177.         printf("-mX = Makrodatei auswerten und berechnen, wobei X der Name der Datei ist\n");
  178.         printf("      in jeder Zeile der Makrodatei steht 'f1 f2 t' wobei:\n");
  179.         printf("      f1 = Frequenz Nummer1\n");
  180.         printf("      f2 = Frequenz Nummer2\n");
  181.         printf("      t  = Dauer in m Sekunden\n");
  182.         printf("-n  = keinen Sound ausgeben (nur Sound berechnen)\n");
  183.         exit(0);
  184.     }
  185.  
  186.     for (i = 0; i < MAXFIELDS; i++) {    /* spielfiles init */
  187.         playfile[i][0] = '\0';
  188.     }
  189.  
  190.     for (i = 1; i < argc; i++) {        /* komandozeilen auswertung */
  191.         if (argv[i][0] == '-') {
  192.             if (argv[i][1] == '2') {
  193.                 portadr = 0x278;
  194.             }
  195.             if (argv[i][1] == '3') {
  196.                 portadr = 0x3BC;
  197.             }
  198.             if (argv[i][1] == 'n') {
  199.                 n = 1;
  200.             }
  201.             if (argv[i][1] == 'l') {
  202.                 if (l+1 <= MAXFIELDS) {
  203.                     strcpy(playfile[l], &argv[i][2]);
  204.                     l++;
  205.                 }
  206.             }
  207.             if (argv[i][1] == 's') {
  208.                 s = 1;
  209.                 strcpy(fstr2, &argv[i][2]);
  210.             }
  211.             if (argv[i][1] == 'm') {
  212.                 m = 1;
  213.                 strcpy(fstr3, &argv[i][2]);
  214.             }
  215.         }
  216.     }
  217.  
  218.     if ((l >= 1  &&  s == 1) || (l == 0  &&  m == 0)) {
  219.         exit(0);
  220.     }
  221.  
  222.     if (m == 1) {    /* makrofile lesen */
  223.         fp = fopen(fstr3, "r");
  224.         if (s == 1) {
  225.             fpspeich = fopen(fstr2, "wb");
  226.         } else {
  227.             fpspeich = fopen("tmp.pcm", "wb");
  228.         }
  229.         printf("PCM-Berechnungsmodus...bitte warten\n");
  230.         if (fp != NULL  &&  fpspeich != NULL) {
  231.             memadr2 = memadr;
  232.             do {
  233.                 i = j = k = 0;
  234.                 fscanf(fp, "%d %d %d\n", &i, &j, &k);
  235.                 printf("freq1=%d Hz / freq2=%d Hz / timing=%d ms          \r", i, j, k);
  236.                 fflush(stdout);
  237.                 wave(i, j, k);
  238.             } while(!feof(fp));
  239.             fclose(fp);
  240.             fclose(fpspeich);
  241.         }
  242.         printf("Berechnung beendet.                            \n");
  243.     }
  244.  
  245.     if (n == 0) {    /* abspielen der tonfolge */
  246.         if (l >= 1)    ;
  247.         else if (s == 1)   strcpy(playfile[0], fstr2);
  248.         else   strcpy(playfile[0], "tmp.pcm");
  249.  
  250.         for (i = 0; i < MAXFIELDS; i++) {    /* felder init */
  251.             memadr[i] = malloc(MAXARRAY);
  252.             if (memadr[i] == NULL) {
  253.                 printf("kein Speicher mehr da");
  254.                 exit(0);
  255.             }
  256.             anzahlfeld[i] = 0L;
  257.         }
  258.  
  259.         for (i = 0; i < MAXFIELDS; i++) {    /* files einlesen */
  260.             if (strlen(playfile[i]) >= 1)   readpcm(playfile[i]);
  261.         }
  262.  
  263.         playfields();
  264.  
  265.         for (i = 0; i < MAXFIELDS; i++) {    /* felder wieder los werden */
  266.             free(memadr[i]);
  267.         }
  268.     }
  269. }
  270.  
  271.